/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022.  All rights reserved.2023.
 */
package service

import (
	"prim-server/logger"
	"prim-server/model"
	fundService "prim-server/service/fund"
	orderService "prim-server/service/order"
	taskService "prim-server/service/task"
	userService "prim-server/service/user"
	"sync"
	"time"
)

const (
	PullCloudOnePayOrderTaskIntervalSecond      = 60
	PullCloudOnDemandResourceTaskIntervalSecond = 60

	PullCloudOnePayBillTaskIntervalSecond   = 60
	PullCloudOnDemandBillTaskIntervalSecond = 60

	PullCloudOnePayResourceFeeTaskIntervalHour   = 1
	PullCloudOnDemandResourceFeeTaskIntervalHour = 2
)

var lock sync.Mutex

// 定时任务拉取云上包周期订单
func PullCloudOnePayOrderTask() {
	go func() {
		logger.Info("Pull cloud one-pay order task init successfully")
		for {
			taskStatus, err := taskService.GetOnePayOrderTaskStatus()
			if err != nil {
				logger.Error(err.Error())
				time.Sleep(PullCloudOnePayOrderTaskIntervalSecond * time.Second)
				continue
			}
			if taskStatus == taskService.TaskRunning {
				time.Sleep(PullCloudOnePayOrderTaskIntervalSecond * time.Second)
				continue
			}
			err = taskService.UpdateOnePayOrderTaskWithStatus(taskService.TaskRunning)
			if err != nil {
				logger.Error(err.Error())
				_ = taskService.UpdateOnePayOrderTaskWithStatus(taskService.TaskStop)
			}
			//获取所有用户ID--排除管理员
			userId, cloudUserId, err := getUserIDAll()
			if err != nil {
				_ = taskService.UpdateOnePayOrderTaskWithStatus(taskService.TaskStop)
				logger.Error(err.Error())
				time.Sleep(PullCloudOnePayOrderTaskIntervalSecond * time.Second)
				continue
			}
			if len(userId) == 0 {
				_ = taskService.UpdateOnePayOrderTaskWithStatus(taskService.TaskStop)
				time.Sleep(PullCloudOnePayOrderTaskIntervalSecond * time.Second)
				continue
			}
			//拉取包周期订单信息
			err = orderService.PullAndSaveCloudOrderLastestAll(userId, nil, cloudUserId)
			if err != nil {
				_ = taskService.UpdateOnePayOrderTaskWithStatus(taskService.TaskStop)
				logger.Error(err.Error())
				time.Sleep(PullCloudOnePayOrderTaskIntervalSecond * time.Second)
				continue
			}
			_ = taskService.UpdateOnePayOrderTaskWithStatus(taskService.TaskStop)
			time.Sleep(PullCloudOnePayOrderTaskIntervalSecond * time.Second)
		}
	}()
}

// 定时任务拉取云上按需资源
func PullCloudOnDemandResourceTask() {
	go func() {
		logger.Info("Pull cloud on-demand resource task init successfully")
		for {
			taskStatus, err := taskService.GetOnDemandOrderTaskStatus()
			if err != nil {
				logger.Error(err.Error())
				time.Sleep(PullCloudOnDemandResourceTaskIntervalSecond * time.Second)
				continue
			}
			if taskStatus == taskService.TaskRunning {
				time.Sleep(PullCloudOnDemandResourceTaskIntervalSecond * time.Second)
				continue
			}
			err = taskService.UpdateOnDemandOrderTaskWithStatus(taskService.TaskRunning)
			if err != nil {
				logger.Error(err.Error())
				_ = taskService.UpdateOnDemandOrderTaskWithStatus(taskService.TaskStop)
			}
			//获取所有用户ID
			userId, cloudUserId, err := getUserIDAll()
			if err != nil {
				_ = taskService.UpdateOnDemandOrderTaskWithStatus(taskService.TaskStop)
				logger.Error(err.Error())
				time.Sleep(PullCloudOnDemandResourceTaskIntervalSecond * time.Second)
				continue
			}
			if len(userId) == 0 {
				_ = taskService.UpdateOnDemandOrderTaskWithStatus(taskService.TaskStop)
				time.Sleep(PullCloudOnDemandResourceTaskIntervalSecond * time.Second)
				continue
			}
			//拉取按需资源信息
			err = orderService.PullAndSaveOnDemandResouceLastestAll(userId, nil, cloudUserId)
			if err != nil {
				_ = taskService.UpdateOnDemandOrderTaskWithStatus(taskService.TaskStop)
				logger.Error(err.Error())
				time.Sleep(PullCloudOnDemandResourceTaskIntervalSecond * time.Second)
				continue
			}
			_ = taskService.UpdateOnDemandOrderTaskWithStatus(taskService.TaskStop)
			time.Sleep(PullCloudOnDemandResourceTaskIntervalSecond * time.Second)
		}
	}()
}

// 支付包周期订单，不依赖账单服务
// 1.对于云上订单，此处直接支付，账单在云上产生，此处只修改订单状态
// 2.对于自有订单，此处直接支付，由调用方产生订单，此处只修改订单状态
// 3.对于云上订单产生的账单，由账单拉取服务生成系统账单
// 4.对于自有订单，由账单服务扫描订单表生成系统账单
// 5.扣费只依赖于账单服务
func PayOnePayOrderEntrance(order *model.OnePayOrder) error {
	//余额账户扣款检查，但是不能立刻扣款
	//扣款只能由账单服务进行
	_, err := fundService.CheckBalanceForReduce(order.UserId, order.PaymentAmount)
	if err != nil {
		logger.Error(err.Error())
		return err
	}
	//信用账户检查
	//修改订单状态
	err = orderService.PayCustomerOnePayOrder(order)
	if err != nil {
		logger.Error(err.Error())
		return err
	}
	//写入账单--如果是系统自有包周期账单则直接写入账单--TODO
	// err =
	return nil
}

// 定时任务拉取云上包周期账单
func PullCloudOnePayBillTask() {
	go func() {
		logger.Info("Pull cloud one-pay bill task init successfully")
		for {
			taskStatus, err := taskService.GetOnePayBillTaskStatus()
			if err != nil {
				logger.Error(err.Error())
				time.Sleep(PullCloudOnePayBillTaskIntervalSecond * time.Second)
				continue
			}
			if taskStatus == taskService.TaskRunning {
				time.Sleep(PullCloudOnePayBillTaskIntervalSecond * time.Second)
				continue
			}
			err = taskService.UpdateOnePayBillTaskWithStatus(taskService.TaskRunning)
			if err != nil {
				logger.Error(err.Error())
				_ = taskService.UpdateOnePayBillTaskWithStatus(taskService.TaskStop)
			}
			//获取所有用户ID--排除管理员
			userId, _, err := getUserIDAll()
			if err != nil {
				_ = taskService.UpdateOnePayBillTaskWithStatus(taskService.TaskStop)
				logger.Error(err.Error())
				time.Sleep(PullCloudOnePayBillTaskIntervalSecond * time.Second)
				continue
			}
			if len(userId) == 0 {
				_ = taskService.UpdateOnePayBillTaskWithStatus(taskService.TaskStop)
				time.Sleep(PullCloudOnePayBillTaskIntervalSecond * time.Second)
				continue
			}
			//拉取包周期订单信息
			err = PullOnePayCloudBillLastestAll(userId)
			if err != nil {
				_ = taskService.UpdateOnePayBillTaskWithStatus(taskService.TaskStop)
				logger.Error(err.Error())
				time.Sleep(PullCloudOnePayBillTaskIntervalSecond * time.Second)
				continue
			}
			_ = taskService.UpdateOnePayBillTaskWithStatus(taskService.TaskStop)
			time.Sleep(PullCloudOnePayBillTaskIntervalSecond * time.Second)
		}
	}()
}

// 定时任务拉取云上包周期资源消费记录
func PullCloudOnePayResourceFeeTask() {
	go func() {
		logger.Info("Pull cloud one-pay resource fee task init successfully")
		for {
			taskStatus, err := taskService.GetOnePayResourceFeeTaskStatus()
			if err != nil {
				logger.Error(err.Error())
				time.Sleep(PullCloudOnePayResourceFeeTaskIntervalHour * time.Hour)
				continue
			}
			if taskStatus == taskService.TaskRunning {
				time.Sleep(PullCloudOnePayResourceFeeTaskIntervalHour * time.Hour)
				continue
			}
			err = taskService.UpdateOnePayResourceFeeTaskWithStatus(taskService.TaskRunning)
			if err != nil {
				logger.Error(err.Error())
				_ = taskService.UpdateOnePayResourceFeeTaskWithStatus(taskService.TaskStop)
			}
			//获取所有用户ID--排除管理员
			userId, _, err := getUserIDAll()
			if err != nil {
				_ = taskService.UpdateOnePayResourceFeeTaskWithStatus(taskService.TaskStop)
				logger.Error(err.Error())
				time.Sleep(PullCloudOnePayResourceFeeTaskIntervalHour * time.Hour)
				continue
			}
			if len(userId) == 0 {
				_ = taskService.UpdateOnePayResourceFeeTaskWithStatus(taskService.TaskStop)
				time.Sleep(PullCloudOnePayResourceFeeTaskIntervalHour * time.Hour)
				continue
			}
			//拉取包周期资源消费记录
			err = PullOnePayCloudResourceFeeLastestAll(userId)
			if err != nil {
				_ = taskService.UpdateOnePayResourceFeeTaskWithStatus(taskService.TaskStop)
				logger.Error(err.Error())
				time.Sleep(PullCloudOnePayResourceFeeTaskIntervalHour * time.Hour)
				continue
			}
			_ = taskService.UpdateOnePayResourceFeeTaskWithStatus(taskService.TaskStop)
			time.Sleep(PullCloudOnePayResourceFeeTaskIntervalHour * time.Hour)
		}
	}()
}

// 定时任务拉取云上按需资源消费记录
func PullCloudOnDemandResourceFeeTask() {
	go func() {
		logger.Info("Pull cloud on-demand resource fee task init successfully")
		for {
			taskStatus, err := taskService.GetOnDemandResourceFeeTaskStatus()
			if err != nil {
				logger.Error(err.Error())
				time.Sleep(PullCloudOnDemandResourceFeeTaskIntervalHour * time.Hour)
				continue
			}
			if taskStatus == taskService.TaskRunning {
				time.Sleep(PullCloudOnDemandResourceFeeTaskIntervalHour * time.Hour)
				continue
			}
			err = taskService.UpdateOnDemandResourceFeeTaskWithStatus(taskService.TaskRunning)
			if err != nil {
				logger.Error(err.Error())
				_ = taskService.UpdateOnDemandResourceFeeTaskWithStatus(taskService.TaskStop)
			}
			//获取所有用户ID--排除管理员
			userId, _, err := getUserIDAll()
			if err != nil {
				_ = taskService.UpdateOnDemandResourceFeeTaskWithStatus(taskService.TaskStop)
				logger.Error(err.Error())
				time.Sleep(PullCloudOnDemandResourceFeeTaskIntervalHour * time.Hour)
				continue
			}
			if len(userId) == 0 {
				_ = taskService.UpdateOnDemandResourceFeeTaskWithStatus(taskService.TaskStop)
				time.Sleep(PullCloudOnDemandResourceFeeTaskIntervalHour * time.Hour)
				continue
			}
			//拉取按需资源消费记录
			err = PullOnDemandCloudResourceFeeLastestAll(userId)
			if err != nil {
				_ = taskService.UpdateOnDemandResourceFeeTaskWithStatus(taskService.TaskStop)
				logger.Error(err.Error())
				time.Sleep(PullCloudOnDemandResourceFeeTaskIntervalHour * time.Hour)
				continue
			}
			_ = taskService.UpdateOnDemandResourceFeeTaskWithStatus(taskService.TaskStop)
			time.Sleep(PullCloudOnDemandResourceFeeTaskIntervalHour * time.Hour)
		}
	}()
}

// get userId and cloudUserId all
func getUserIDAll() (userId, cloudUserId []string, err error) {
	//获取所有用户ID
	cloudUsers, err := userService.GetCloudUserAll(nil)
	if err != nil {
		logger.Error(err.Error())
		return nil, nil, err
	}
	if len(cloudUsers) == 0 {
		return nil, nil, nil
	}
	admin, err := userService.GetAdminId()
	if err != nil {
		logger.Error(err.Error())
		return nil, nil, err
	}
	for _, cloudUser := range cloudUsers {
		if cloudUser.UserId == admin {
			continue
		}
		userId = append(userId, cloudUser.UserId)
		cloudUserId = append(cloudUserId, cloudUser.CloudId)
	}
	return userId, cloudUserId, nil
}
